package com.ceba.test.modules.admin.helper;


import com.ceba.base.enums.SealTypeEnum;
import com.ceba.base.utils.CreateQRCode;
import com.ceba.base.utils.PDFUtils;
import com.ceba.base.utils.ToPdfUtils;
import com.ceba.cebautils.FileUtils;
import com.ceba.cebautils.IDUtils;
import com.ceba.cebautils.StringUtil;
import com.ceba.qr.facade.QrBaseFacade;
import com.ceba.test.base.config.LogicPathUtil;
import com.ceba.test.base.enums.QrServiceMethodEnum;
import com.ceba.test.modules.storage.logicService.StorageFileCacheManage;
import com.httpclient.HttpClientUtil;
import com.httpclient.common.HttpConfig;
import com.httpclient.common.HttpHeader;
import org.apache.http.Header;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ceba.test.base.configs.CebaConfig;
import com.ceba.test.base.helper.SystemHelper;


import java.io.File;
import java.net.URLEncoder;
import java.util.*;

public class QRCodeHelper {
	
	static Logger logger = LoggerFactory.getLogger(QRCodeHelper.class);


    /**
     * 生成能扫描的二维码链接
     * @param fileId
     * @return
     */
    private static String createQRLink(String fileId) {
        if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_CODE.getCode()){
            try {
                return QrBaseFacade.getQrContentUrl(fileId);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.BE.getCode()){
            String prefix = StringUtil.addLastSlash(CebaConfig.QR_SERVER_IP_PORT) +
                    CebaConfig.QR_SERVER_PREFIX;
            String queryUrl = CebaConfig.QR_PDF_QUERY_ITF;
            if (prefix.indexOf("?") > 0 || queryUrl.indexOf("?") > 0) {
                queryUrl = prefix + queryUrl + "&fileId=" + fileId;
            } else {
                queryUrl = prefix + queryUrl + "?fileId=" + fileId;
            }
            return queryUrl;
        } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_NUOAN.getCode()) {
            /**
             * 诺安的二维码URL是如下格式
             * "https://coa.mxns.com.cn/qr/12345678901234567890123456789021";
             */
            StringBuilder sbQueryUrl = new StringBuilder(CebaConfig.QR_PDF_QUERY_ITF);
            sbQueryUrl.append("/");
            sbQueryUrl.append(fileId);
            return sbQueryUrl.toString();
        } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_RONGDA.getCode()) {
            /**
             * 诺安的二维码URL是如下格式
             * "http://qr.rd-test.com/#/?qr=12345678901234567890123456789021";
             */
            StringBuilder sbQueryUrl = new StringBuilder(CebaConfig.QR_PDF_QUERY_ITF);
            if (!CebaConfig.QR_PDF_QUERY_ITF.endsWith("/")) {
                sbQueryUrl.append("/");
            }
            sbQueryUrl.append("#/?qr=");
            sbQueryUrl.append(fileId);
            return sbQueryUrl.toString();
        } else {
            return null;
        }
    }


	/*
	 * 是否插入二维码，返回文档路径
	 * 根据ID对应的生成二维码，但不保存到FM中
	 * 完整版和简版中 id= reportId
	 * 极简版 id = fileId
	 */
	public static String needInsertQRImage(String filePath,String outPath,String fileId) throws Exception{
		if(SystemHelper.canUseQR()){
			String qrcPath = LogicPathUtil.getPhysicalTempFolder(StorageFileCacheManage.getSystemUseAddressId()) + IDUtils.getGuid()+".png";
			logger.info("generate qr link fileId = " + fileId);
			String context=createQRLink(fileId);
			logger.info("generate qr link = " + context);
			if (!StringUtil.isEmptyString(context)) {
			    boolean encoderQRCodeFlag = false;
			    if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_NUOAN.getCode()) {
                    String logoImgPath = LogicPathUtil.getPhysicalPicFolder(StorageFileCacheManage.getSystemUseAddressId()) + "logo_nuoan.png";
                    String detectImgPath = LogicPathUtil.getPhysicalPicFolder(StorageFileCacheManage.getSystemUseAddressId()) + "detect_nuoan.png";
                    encoderQRCodeFlag = QrCodePlugin.encoderQRCode(context, "扫码查看在线报告", logoImgPath, detectImgPath, qrcPath);
                } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_RONGDA.getCode()) {
                    String logoImgPath = LogicPathUtil.getPhysicalPicFolder(StorageFileCacheManage.getSystemUseAddressId()) + "logo_rongda.png";
                    String detectImgPath = LogicPathUtil.getPhysicalPicFolder(StorageFileCacheManage.getSystemUseAddressId()) + "detect_nuoan.png";
                    encoderQRCodeFlag = QrCodePlugin.encoderQRCode(context, "扫码查看在线报告", logoImgPath, detectImgPath, qrcPath);
                } else {
                    encoderQRCodeFlag = CreateQRCode.encoderQRCode(context, qrcPath, "png", 7);
                }

			    if (encoderQRCodeFlag) {
                    JSONObject gs = new JSONObject();
                    gs.put("matchName", CebaConfig.QRCODE_MATCH_NAME);
                    gs.put("imgWidth", CebaConfig.QRCODE_WIDTH);
                    gs.put("imgHeight", CebaConfig.QRCODE_HEIGTH);
                    gs.put("filePath", qrcPath);
                    outPath = PDFUtils.insertQRImage(outPath, filePath, gs);
                }
			}
            //二维码文档不存在，则保留原来的
            if (!FileUtils.isFile((outPath))) {
                outPath = filePath;
                logger.error("generate qr link fail,fileId = " + fileId);
            }
		}else{
			outPath = filePath;
		}
		return outPath;
	}
	
	/**
	 * 根据ID对应的生成二维码，但不保存到FM中
	 * 完整版和简版中 id= reportId
	 * 极简版 id = fileId
	 * 接口则随机生成id=ID.getGUID();
	 * @return
	 */
    public static boolean sendQRPdfToServer(String fileId,String filePath){
        boolean ret = false;
        if(("true".equals(CebaConfig.QR_PDF_NEED_UPLOAD) || "async".equals(CebaConfig.QR_PDF_NEED_UPLOAD)) && "true".equals(CebaConfig.QRCODE)){
            if(SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_CODE.getCode()){
                logger.info("begin upload qr file fail,fileId = " + fileId+",filePath="+filePath);
                try {
                    ret = QrBaseFacade.uploadQrToFileService(fileId,filePath);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("upload qr file fail,fileId = " + fileId+",filePath="+filePath);
                }
                if(ret){
                    logger.info("upload qr file success.");
                } else {
                    logger.error("upload qr file fail,fileId = " + fileId+",filePath="+filePath);
                }
            }else if(SystemHelper.qrServiceMethod() == QrServiceMethodEnum.BE.getCode()) {
                //适用于BE配置页面的二维码
                JSONObject o = new JSONObject();
                o.put("fileId", fileId);
                o.put("filePath", filePath);
                String uploadUrl = StringUtil.addLastSlash(CebaConfig.QR_SERVER_IP_PORT) +
                        CebaConfig.QR_SERVER_PREFIX + CebaConfig.QR_PDF_UPLOAD_ITF;
                o.put("qrPdfUploadItf", uploadUrl);
                o.put("qrPdfQueryItf", createQRLink(fileId));
                ret = uploadQRPdf(o.toString());
                //适用于BE配置页面的二维码 end
            } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_NUOAN.getCode()) {
                JSONObject o = new JSONObject();
                o.put("fileId", fileId);
                o.put("filePath", filePath);
                o.put("qrPdfUploadItf", CebaConfig.QR_PDF_UPLOAD_ITF);
                o.put("qrPdfQueryItf", createQRLink(fileId));
                ret = uploadQRPdfToNuoan(o);
            } else if (SystemHelper.qrServiceMethod() == QrServiceMethodEnum.QR_RONGDA.getCode()) {
                JSONObject o = new JSONObject();
                o.put("fileId", fileId);
                String picPath = filePath.substring(0, filePath.lastIndexOf("pdf")) + "png";
                String realPicPath = filePath.substring(0, filePath.lastIndexOf("pdf")) + "png0.png";
                if (!new File(realPicPath).exists()) {
                    ToPdfUtils.PdfPageToPic(filePath, picPath, 2.5f, "png", 0);
                }
                o.put("filePath", realPicPath);
                o.put("qrPdfUploadItf", CebaConfig.QR_PDF_UPLOAD_ITF);
                o.put("qrPdfQueryItf", fileId);
                ret = uploadQRPdfToNuoan(o);
                if (ret) {
                    new File(realPicPath).delete();
                }
            }
        }
        return ret;
    }

    /**
     * { "fileId":, "filePath":,"qrPdfUploadItf":,"qrPdfQueryItf": }
     * 返回
     * {"result":true,"message":""}
     * @param json
     * @return
     */
    public static boolean uploadQRPdf(String json) {
        boolean ret = false;
        String fileId = "";
        String filePath = "";
        String qrPdfUploadItf="";
        try {
            JSONObject o = new JSONObject(json);
            String qrPdfQueryItf = "";
            if (o.has("fileId")) {
                fileId = o.getString("fileId");
            }
            if (o.has("filePath")) {
                filePath = o.getString("filePath");
            }
            if (o.has("qrPdfUploadItf")) {
                qrPdfUploadItf = o.getString("qrPdfUploadItf");
            }
            if (o.has("qrPdfQueryItf")) {
                qrPdfQueryItf = o.getString("qrPdfQueryItf");
            }

            String fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.length());
            fileName = URLEncoder.encode(fileName, "utf-8");
            Map<String,Object> maps = new HashMap<String,Object>();
            maps.put("qrQueryUrl", URLEncoder.encode(qrPdfQueryItf,"utf-8"));
            Header[] headers =  HttpHeader.custom()
                    .userAgent("Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; Gecko)").build();
            if(qrPdfUploadItf.indexOf("http") <0){
                qrPdfUploadItf = "http://"+qrPdfUploadItf;
            }
            HttpConfig httpConfig = HttpConfig.custom().url(qrPdfUploadItf)
                    .headers(headers).encoding("utf-8").files(new String[]{
                            filePath
                    }).map(maps);
            String re = HttpClientUtil.post(httpConfig);
            if (re != null) {
                JSONObject jsonr = new JSONObject(re);
                if (jsonr.has("result") && jsonr.getBoolean("result")) {
                    logger.debug("upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "成功");
                    ret = true;
                } else {
                    logger.error("upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "失败");
                }
                System.out.println(re);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            logger.error("upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "失败");
        }

        return ret;
    }

    public static boolean uploadQRPdfToNuoan(JSONObject o) {
        boolean ret = false;
        String fileId = "";
        String filePath = "";
        String qrPdfUploadItf="";
        String qrPdfQueryItf = "";
        try {
            if (o.has("fileId")) {
                fileId = o.getString("fileId");
            }
            if (o.has("filePath")) {
                filePath = o.getString("filePath");

                /**
                 * 解决诺安重传时找不到文件的问题。LIMS签名获取文件后，会把文件移动到新建的success/error目录下；因此需要在这些目录下重拾寻找。
                 */
                File file = new File(filePath);
                if (!file.exists()) {
                    String successFilePath = file.getParent() + File.separator + "success" + File.separator + file.getName();

                    File successFile = new File(successFilePath);
                    if (!successFile.exists()) {
                        String failFilePath = file.getParent() + File.separator + "error" + File.separator + file.getName();

                        File failFile = new File(failFilePath);
                        if (!failFile.exists()) {
                            logger.error("uploadQRPdfToNuoan: upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "失败");
                            logger.error("uploadQRPdfToNuoan: 文件不存在");
                            return ret;
                        } else {
                            filePath = failFilePath;
                        }
                    } else {
                        filePath = successFilePath;
                    }
                }
            }
            if (o.has("qrPdfUploadItf")) {
                qrPdfUploadItf = o.getString("qrPdfUploadItf");
            }
            if (o.has("qrPdfQueryItf")) {
                qrPdfQueryItf = o.getString("qrPdfQueryItf");
            }

            Map<String,Object> maps = new HashMap<String,Object>();
            maps.put("url", qrPdfQueryItf);
            maps.put("isUpsert", false);
            Header[] headers =  HttpHeader.custom()
                    .userAgent("Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; Gecko)").build();
            if(qrPdfUploadItf.indexOf("http") <0){
                qrPdfUploadItf = "http://"+qrPdfUploadItf;
            }
            HttpConfig httpConfig = HttpConfig.custom()
                    .url(qrPdfUploadItf)
                    .headers(headers)
                    .encoding("utf-8")
                    .files(new String[]{filePath})
                    .map(maps);
            logger.info("uploadQRPdfToNuoan: 开始 upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf);
            String re = HttpClientUtil.post(httpConfig);
            if (re != null) {
                logger.info("uploadQRPdfToNuoan: 结束 upload" + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + " return: " + re);
                JSONObject jsonr = new JSONObject(re);
                if (jsonr.has("code") && jsonr.getInt("code") == 0) {
                    logger.info("uploadQRPdfToNuoan: upload " + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "成功");
                    ret = true;
                } else {
                    logger.error("uploadQRPdfToNuoan: upload " + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "失败");
                    logger.error(re);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            logger.error("uploadQRPdfToNuoan: upload " + filePath + "，fileId = " + fileId + "到" + qrPdfUploadItf + "失败");
        }

        return ret;
    }

    public static JSONObject getQrJson() {
        JSONObject crJsonStamp = new JSONObject();
        crJsonStamp.put("sealType", SealTypeEnum.KEYWORD_STAMP_FLAG.getType());
        crJsonStamp.put("imgWidth", CebaConfig.QRCODE_WIDTH);
        crJsonStamp.put("imgHeight", CebaConfig.QRCODE_HEIGTH);
        crJsonStamp.put("matchName", CebaConfig.QRCODE_MATCH_NAME);
        return crJsonStamp;
    }

}
